<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>业务参数配置</title>
        <script src="/lib/axios.js"></script>
        <script src="/lib/vue.js"></script>
        <link rel="stylesheet" href="/lib/elementindex.css">
        <script src="/lib/elementindex.js"></script>
    </head>
    <style>
        .cell
        {
            white-space: nowrap!important;
        }
        .validfailed
        {
            border: solid 1px red;
        };
        input : focus
        {
            border: solid 5px red!important;
            background-color:yellow!important;
        }
</style>
    <body>

        <div id="app" style="width:100%">
            <el-card>
                <div slot="header">
                    <span>{{component.rname}}</span>
                    <el-button style="float: right; padding: 3px 0" type="text" @click="handleBasicSettingDlg()">基本信息
                    </el-button>
                </div>
                <div style="font-size: 0.875rem;margin-bottom: 1.125rem;">
                    <span>{{component.description}}</span>
                </div>
            </el-card></br>
            <el-form ref="form" :model='ruleDef' label-width="auto">
                <el-table ref='table' highlight-current-row :indent='20' :data="ruleDef.list" style="width: 100%;margin-bottom: 20px;"
                    row-key="id" border :tree-props="{children: 'list'}">
                    <!-- default-expand-all -->
                    <el-table-column label="#参数代码" prop='id'>
                        <template slot="header">
                            <span>#参数代码</span>
                            <el-tooltip content="Bottom center" placement="bottom" effect="light">
                                <i class="el-icon-info"></i>
                                <div slot="content">
                                    <li>参数代码是给参数的命名代码，类似于程序员给变量或常量的命名，通过参数代码使用对应参数数值； </li>
                                    <li>参数代码必须提供，不能为空； </li>
                                    <li>中英文字符开头，字符和数字构成，不包括空白及特殊字符，如~！@#￥$%……&*（）《》？：“，。、；‘·等</li>
                                </div>
                            </el-tooltip>
                        </template>
                        <template slot-scope="scope">
                            <span><span style="color:lightgray">{{scope.row.id}}</span>
                                <input maxlength='100' :id="'code'+scope.row.id" v-model.trim="scope.row.code" class='el-input__inner'
                                    style="width: 80%;" placeholder="供程序使用的参数代码" :onblur:native='handleCodeBlur(scope.row)'
                                    onkeyup="value=$util.tokentrim(value)" onbeforepaste="clipboardData.setData('text',$util.tokentrim(clipboardData.getData('text')))"></input>
                            </span>
                        </template>
                    </el-table-column>
                    <el-table-column prop="type" label="数据类型" width='100px'>
                        <template slot="header">
                            <span>数据类型</span>
                            <el-tooltip content="Bottom center" placement="bottom" effect="light">
                                <i class="el-icon-info"></i>
                                <div slot="content">
                                    <li>数据类型包括文本、数组、对象三种类型，对象类型是灵活且复杂的类型，由其子数据项依次构成； </li>
                                    <li>数据类型必须提供，默认为文本类型； </li>
                                </div>
                            </el-tooltip>
                        </template>
                        <template slot-scope="scope">
                            <el-select style='width: 100%;' v-model="scope.row.type" placeholder="请选择">
                                <el-option v-for="item in dataTypeList" :value='item.code' :label='item.name' :key="item.code">
                                </el-option>
                            </el-select>
                        </template>

                    </el-table-column>

                    <el-table-column label="参数数值" prop="value">
                        <template slot="header">
                            <span>参数数值</span>
                            <el-tooltip content="Bottom center" placement="bottom" effect="light">
                                <i class="el-icon-info"></i>
                                <div slot="content">
                                    <li>参数数值的内容需要与数据类型保持一致，数字对数字、文本对文本； </li>
                                    <li>对象类型时可以不做设置，或者是java语言下的一个class的全名称且class已经被系统装载；</li>
                                </div>
                            </el-tooltip>
                        </template>
                        <template slot-scope="scope">
                            <!-- 
                            <span v-if="scope.row.type=='object'" style="color: lightgray; "></span>
                            <el-input v-else v-model="scope.row.value" type='text' placeholder="参数数值"></el-input> -->
                            <el-input maxlength='1000' v-model="scope.row.value" :type="scope.row.type=='number'?'number':'text'"
                                placeholder="参数数值"></el-input>
                        </template>
                    </el-table-column>

                    <el-table-column label="名称/说明">
                        <template slot="header">
                            <span>名称/说明</span>
                            <el-tooltip content="Bottom center" placement="bottom" effect="light">
                                <i class="el-icon-info"></i>
                                <div slot="content">
                                    <li>参数的对用户友好的名字或说明性信息； </li>
                                    <li>可以是任意文本内容；</li>
                                </div>
                            </el-tooltip>
                        </template>
                        <template slot-scope="scope">
                            <el-input maxlength='1000' v-model="scope.row.name" type="text" placeholder="供用户参考的名称/说明"></el-input>
                        </template>
                    </el-table-column>

                    <el-table-column label="操作" width='200px'>
                        <template slot="header">
                            <span>操作</span>
                            <el-tooltip content="Bottom center" placement="bottom" effect="light">
                                <i class="el-icon-info"></i>
                                <div slot="content">
                                    <li>追加记录(+) :在表格末尾增加一条记录；</li>
                                    <li> 子项(+) :为在当前记录(对象类型)增加一条子记录； </li>
                                    <li> +(插入纪录) :在当前记录之上插入一条新纪录； </li>
                                    <li> ×(删除记录) :删除当前记录；</li>
                                </div>
                            </el-tooltip>
                            <el-button type="success" size='mini' @click="handleAppend">追加记录(+)
                            </el-button>
                        </template>
                        <template slot-scope="scope">
                            <el-button v-if="scope.row.type=='object'" type="success" plain size='mini' @click="handleAppendChild(scope.row)">子项(+)</el-button>
                            <el-button size='mini' @click="handleInsert(scope.row)" placeholder="">+</el-button>
                            <el-button size='mini' @click="handleRemove(scope.row)">×</el-button>

                        </template>
                    </el-table-column>
                </el-table>

                <el-form-item label="">
                    <el-button type="primary" @click='handleUpdateRuleEvent'>保存修改</el-button>
                </el-form-item>
            </el-form>

        </div>

        <script type='module'>
            import * as $util from '/lib/hc-util.js'
            window.$util = $util; //for html document event
            import * as $rest from '../lib/hc-rest-service.js'
            import RuleBasicSetting from '/com/hc-rule-basic-properties.js'
            
            $rest.check$pinfoOrLoad(onready, 'xsxdjc/Main');
            
            function onready() {
                window.vmsetting = new RuleBasicSetting();
                window.vm = new Vue({
                    el: '#app',
                    data: {
                        ruleDef: {},
                        dataTypeList: $util.hc$data$type$list,
                        component: $config.componentMap['data:setting'],
                    },
                    methods: {
                        handleBasicSettingDlg:function()
                        {
                            vmsetting.show(this.ruleDef)
                        },
                        handleCodeBlur: function(row) {
                            let e = document.getElementById('code' + row.id);
                            if (!e) return;
                            if (!row.code) {
                                $util.addClass(e, 'validfailed');
                                e.placeholder = '代码必须提供';
                                e.focus();
                            } else $util.removeClass(e, 'validfailed');
                        },
                        validateCodeAll: function() {
                            let set = [];

                            let ret = validateCode(this.ruleDef.list);
                            return {
                                ret: ret,
                                set: set
                            };

                            function validateCode(list, path = '') {
                                let ret = false;
                                if (!list) return ret;

                                for (let i in list) {
                                    let it = list[i]
                                    ret = ret || (!it.code);
                                    if (!it.code) {
                                        let e = document.getElementById('code' + it.id);
                                        $util.addClass(e, 'validfailed');
                                        e.placeholder = '代码必须提供';

                                        set.push(path + it.id);
                                        // e.focus();
                                    }
                                    //function called firstly is necessary, and then or ret
                                    ret = validateCode(it.list, path + it.id + '→') || ret;
                                };

                                return ret;
                            }

                        },

                        handleUpdateRuleEvent: function() {
                            let valid = this.validateCodeAll();
                            if (valid.ret) {
                                this.$message({
                                    dangerouslyUseHTMLString: true,
                                    message: '以下代码内容为空,不能保存！#如下：<br/><li>' + valid.set.join(
                                        ';</li><li>') + ';</li>',
                                    type: 'warning',
                                })
                                return;
                            }
                            $rest.updateRuleDefInVm(this);
                        },
                        getItem: function(list, id) {
                            if (!list) return null;
                            for (let i = 0; i < list.length; i++) {
                                if (list[i].id === id) {
                                    return {
                                        list: list,
                                        index: i
                                    };
                                } else {
                                    let finded = this.getItem(list[i].list, id);
                                    if (finded) return finded;
                                };
                            };
                            return null;
                        },
                        newItem: function() {
                            return {
                                id: ++this.ruleDef.rmaxid,
                                code: '',
                                name: '',
                                type: 'text',
                                value: null,
                                list: null,
                            };
                        },
                        handleAppend: function() {
                            this.insertRow(this.ruleDef.list, this.newItem());
                        },
                        handleInsert: function(row) {
                            let node = this.getItem(this.ruleDef.list, row.id);
                            if (node) {
                                this.insertRow(node.list, this.newItem(), node.index);
                            } else console.error('the row is not found.', row);
                        },
                        handleRemove: function(row) {
                            let node = this.getItem(this.ruleDef.list, row.id);
                            if (!node) console.error('the row is not found.', row);
                            if(row.type =='object')
                            {
                                this.$confirm('删除对象会同时删除所有子项内容, 是否继续?', '提示', {
                                    cancelButtonText: '取消',
                                    confirmButtonText: '确定',
                                    type: 'warning',
                                    center: true
                                }).then(
                                    () => {
                                        node.list.splice(node.index, 1);
                                    }
                                ).catch(
                                    () => {}
                                );
                            }
                            else node.list.splice(node.index, 1);
                           
                        },
                        insertRow: function(list, newItem, index = -1) {
                            if (index >= 0) list.splice(index, 0, newItem);
                            else list.push(newItem);
                            this.$nextTick(function() {
                                document.getElementById('code' + newItem.id).focus()
                            })
                        },
                        handleAppendChild: function(row) {
                            row.list = row.list || [];
                            this.insertRow(row.list, this.newItem());
                            
                            let table =this.$refs.table;
                            this.$nextTick(()=>{table.toggleRowExpansion(row, true);})
                        },
                    }
                });
                
               $rest.obtainRuleDefByRpath($pinfo.pcode() + '/Setting',
                    function(ruleDef) {
                        vm.ruleDef = ruleDef;
                    });
            }
        </script>
    </body>

</html>
